%option noyywrap
%{
/*****************声明和选项设置  begin*****************/
#include <stdio.h>
#include <stdlib.h>

#include "lexical_analyzer.h"

int lines;
int pos_start;
int pos_end;

/*****************声明和选项设置  end*****************/

%}

IDENTIFIER [a-zA-Z]+
INTEGER 0|[1-9][0-9]*
FLOATPOINT {INTEGER}\.[0-9]*
ARRAY \[\]
LETTER \'.\'
EOL [\n]+
BLANK [ ]+
WITHOUT ([^\*]|\*+[^\/])*  
COMMENT \/\*([^\*]|\*+[^\/])*\*+\/ 
TAB [\t]+
%%

 /******************TODO*********************/
 /****请在此补全所有flex的模式与动作  start******/
 //STUDENT TO DO
"+" {pos_start = pos_end;pos_end +=strlen(yytext);return ADD;}
"-" {pos_start = pos_end;pos_end +=strlen(yytext);return SUB;}
"*" {pos_start = pos_end;pos_end +=strlen(yytext);return MUL;}
"/" {pos_start = pos_end;pos_end +=strlen(yytext);return DIV;}
"<" {pos_start = pos_end;pos_end +=strlen(yytext);return LT;}
"<=" {pos_start = pos_end;pos_end +=strlen(yytext);return LTE;}
">" {pos_start = pos_end;pos_end +=strlen(yytext);return GT;}
">=" {pos_start = pos_end;pos_end +=strlen(yytext);return GTE;}
"==" {pos_start = pos_end;pos_end +=strlen(yytext);return EQ;}
"!=" {pos_start = pos_end;pos_end +=strlen(yytext);return NEQ;}
"=" {pos_start = pos_end;pos_end +=strlen(yytext);return ASSIN;}
";" {pos_start = pos_end;pos_end+=strlen(yytext);return SEMICOLON;}
"," {pos_start = pos_end;pos_end+=strlen(yytext);return COMMA;}
"\(" {pos_start = pos_end;pos_end +=strlen(yytext);return LPARENTHESE;}
"\)" {pos_start = pos_end;pos_end +=strlen(yytext);return RPARENTHESE;}
"\[" {pos_start = pos_end;pos_end +=strlen(yytext);return LBRACKET;}
"\]" {pos_start = pos_end;pos_end +=strlen(yytext);return RBRACKET;}
"\{" {pos_start = pos_end;pos_end +=strlen(yytext);return LBRACE;}
"\}" {pos_start = pos_end;pos_end +=strlen(yytext);return RBRACE;}
"else" {pos_start = pos_end;pos_end +=strlen(yytext);return ELSE;}
"if" {pos_start = pos_end;pos_end +=strlen(yytext);return IF;}
"int" {pos_start = pos_end;pos_end +=strlen(yytext);return INT;}
"float" {pos_start = pos_end;pos_end +=strlen(yytext);return FLOAT;}
"return" {pos_start = pos_end;pos_end +=strlen(yytext);return RETURN;}
"void" {pos_start = pos_end;pos_end +=strlen(yytext);return VOID;}
"while" {pos_start = pos_end;pos_end +=strlen(yytext);return WHILE;}

{IDENTIFIER} {pos_start = pos_end;pos_end +=strlen(yytext);return IDENTIFIER;}
{INTEGER} {pos_start = pos_end;pos_end +=strlen(yytext);return INTEGER;}
{FLOATPOINT} {pos_start = pos_end;pos_end +=strlen(yytext);return FLOATPOINT;}
{ARRAY} {pos_start = pos_end;pos_end +=strlen(yytext);return ARRAY;}
{LETTER} {pos_start = pos_end;pos_end+=strlen(yytext);return LETTER;}

{EOL} {return EOL;}
(\/\*({WITHOUT}|{COMMENT})\*+\/)|(\\\\+(.)*) {return COMMENT;}
{BLANK} {return BLANK;}
{TAB} {pos_start=pos_end;pos_end+=strlen(yytext);}

. {return ERROR;}

%%

 /****请在此补全所有flex的模式与动作  end******/

/****************C代码 start*************/

/// \brief analysize a *.cminus file
///
/// \param input_file, 需要分析的文件路径
/// \param token stream, Token_Node结构体数组，用于存储分析结果，具体定义参考lexical_analyer.h

void analyzer(char* input_file, Token_Node* token_stream){
    lines = 1;
    pos_start = 1;
    pos_end = 1;
    if(!(yyin = fopen(input_file,"r"))){
        printf("[ERR] No input file\n");
        exit(1);
    }
    printf("[START]: Read from: %s\n", input_file);

    int token;
    int index = 0;

    while(token = yylex()){
        switch(token){
            case COMMENT:
                //STUDENT TO DO
                int i = 0;
                int len = strlen(yytext);
                for(i;i<len;i++)
                {
                    if(yytext[i]=='\n')
                    {
                        pos_start=pos_end=1;
                        lines+=1;
                    }
                    else pos_end+=1;
                }
                break;
            case BLANK:
                //STUDENT TO DO
                pos_end +=strlen(yytext);
                pos_start=pos_end;
                break;
            case EOL:
                //STUDENT TO DO
                lines+=strlen(yytext);
                pos_start=pos_end=1;
                break;
            case ERROR:
                printf("[ERR]: unable to analysize %s at %d line, from %d to %d\n", yytext, lines, pos_start, pos_end);
            default :
                if (token == ERROR){
                    sprintf(token_stream[index].text, "[ERR]: unable to analysize %s at %d line, from %d to %d", yytext, lines, pos_start, pos_end);
                } else {
                    strcpy(token_stream[index].text, yytext);
                }
                token_stream[index].token = token;
                token_stream[index].lines = lines;
                token_stream[index].pos_start = pos_start;
                token_stream[index].pos_end = pos_end;
                index++;
                if (index >= MAX_NUM_TOKEN_NODE){
                    printf("%s has too many tokens (> %d)", input_file, MAX_NUM_TOKEN_NODE);
                    exit(1);
                }
        }
    }
    printf("[END]: Analysis completed.\n");
    return;
}



/****************C代码 end*************/
